home *** CD-ROM | disk | FTP | other *** search
/ Aminet 25 / Aminet 25 (1998)(GTI - Schatztruhe)[!][Jun 1998].iso / Aminet / game / shoot / ADoom_src_1_2.lha / ADoom_src / r_plane.c < prev    next >
C/C++ Source or Header  |  1998-02-20  |  10KB  |  517 lines

  1. // Emacs style mode select   -*- C++ -*- 
  2. //-----------------------------------------------------------------------------
  3. //
  4. // $Id:$
  5. //
  6. // Copyright (C) 1993-1996 by id Software, Inc.
  7. //
  8. // This source is available for distribution and/or modification
  9. // only under the terms of the DOOM Source Code License as
  10. // published by id Software. All rights reserved.
  11. //
  12. // The source is distributed in the hope that it will be useful,
  13. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
  15. // for more details.
  16. //
  17. // $Log:$
  18. //
  19. // DESCRIPTION:
  20. //    Here is a core component: drawing the floors and ceilings,
  21. //     while maintaining a per column clipping list only.
  22. //    Moreover, the sky areas have to be determined.
  23. //
  24. //-----------------------------------------------------------------------------
  25.  
  26.  
  27. static const char
  28. rcsid[] = "$Id: r_plane.c,v 1.4 1997/02/03 16:47:55 b1 Exp $";
  29.  
  30. #include <stdlib.h>
  31.  
  32. #include "i_system.h"
  33. #include "z_zone.h"
  34. #include "w_wad.h"
  35.  
  36. #include "doomdef.h"
  37. #include "doomstat.h"
  38.  
  39. #include "r_local.h"
  40. #include "r_sky.h"
  41.  
  42.  
  43.  
  44. planefunction_t        floorfunc;
  45. planefunction_t        ceilingfunc;
  46.  
  47. //
  48. // opening
  49. //
  50.  
  51. // Here comes the obnoxious "visplane".
  52. #define MAXVISPLANES    128
  53. //#define MAXVISPLANES    1024
  54. FAR visplane_t        visplanes[MAXVISPLANES];
  55. visplane_t*        lastvisplane;
  56. visplane_t*        floorplane;
  57. visplane_t*        ceilingplane;
  58.  
  59. // ?
  60. //#define MAXOPENINGS    SCREENWIDTH*64
  61. #define MAXOPENINGS    SCREENWIDTH*128
  62. //FAR short        openings[MAXOPENINGS];
  63. short            *openings;
  64. short*            lastopening;
  65.  
  66.  
  67. //
  68. // Clip values are the solid pixel bounding the range.
  69. //  floorclip starts out SCREENHEIGHT
  70. //  ceilingclip starts out -1
  71. //
  72. //short            floorclip[SCREENWIDTH];
  73. //short            ceilingclip[SCREENWIDTH];
  74. short            *floorclip;
  75. short            *ceilingclip;
  76.  
  77.  
  78. //
  79. // spanstart holds the start of a plane span
  80. // initialized to 0 at start
  81. //
  82. //FAR int            spanstart[SCREENHEIGHT];
  83. //FAR int            spanstop[SCREENHEIGHT];
  84. int                *spanstart;
  85. int                *spanstop;
  86.  
  87. //
  88. // texture mapping
  89. //
  90. lighttable_t**        planezlight;
  91. fixed_t            planeheight;
  92.  
  93. //FAR fixed_t        yslope[SCREENHEIGHT];
  94. //FAR fixed_t        distscale[SCREENWIDTH];
  95. fixed_t            *yslope;
  96. fixed_t            *distscale;
  97. fixed_t            basexscale;
  98. fixed_t            baseyscale;
  99.  
  100. //FAR fixed_t        cachedheight[SCREENHEIGHT];
  101. //FAR fixed_t        cacheddistance[SCREENHEIGHT];
  102. //FAR fixed_t        cachedxstep[SCREENHEIGHT];
  103. //FAR fixed_t        cachedystep[SCREENHEIGHT];
  104. fixed_t            *cachedheight;
  105. fixed_t            *cacheddistance;
  106. fixed_t            *cachedxstep;
  107. fixed_t            *cachedystep;
  108.  
  109.  
  110. void resinit_r_plane (void)  //called before anything else
  111. {
  112.   int i;
  113.  
  114.   //use calloc instead of malloc in case doom depends on global vars being
  115.   //initialized to 0
  116.   for (i = 0; i < MAXVISPLANES; i++) {
  117.     unsigned short *blah;
  118.  
  119.     blah = (unsigned short *)I_calloc(SCREENWIDTH*2+4, sizeof(unsigned short));
  120.     visplanes[i].top = blah + 1;
  121.     visplanes[i].bottom = blah + SCREENWIDTH + 3;
  122.   }
  123.   openings = (short *)I_calloc (MAXOPENINGS, sizeof(short));
  124.   floorclip = (short *)I_calloc (SCREENWIDTH, sizeof(short));
  125.   ceilingclip = (short *)I_calloc (SCREENWIDTH, sizeof(short));
  126.   spanstart = (int *)I_calloc (SCREENHEIGHT, sizeof(int));
  127.   spanstop = (int *)I_calloc (SCREENHEIGHT, sizeof(int));
  128.  
  129.   yslope = (fixed_t *)I_calloc (SCREENHEIGHT, sizeof(fixed_t));
  130.   distscale = (fixed_t *)I_calloc (SCREENWIDTH, sizeof(fixed_t));
  131.   cachedheight = (fixed_t *)I_calloc (SCREENHEIGHT, sizeof(fixed_t));
  132.   cacheddistance = (fixed_t *)I_calloc (SCREENHEIGHT, sizeof(fixed_t));
  133.   cachedxstep = (fixed_t *)I_calloc (SCREENHEIGHT, sizeof(fixed_t));
  134.   cachedystep = (fixed_t *)I_calloc (SCREENHEIGHT, sizeof(fixed_t));
  135. }
  136.  
  137.  
  138. //
  139. // R_InitPlanes
  140. // Only at game startup.
  141. //
  142. void R_InitPlanes (void)
  143. {
  144.   // Doh!
  145. }
  146.  
  147.  
  148. #ifndef AMIGA
  149. //
  150. // R_MapPlane
  151. //
  152. // Uses global vars:
  153. //  planeheight
  154. //  ds_source
  155. //  basexscale
  156. //  baseyscale
  157. //  viewx
  158. //  viewy
  159. //
  160. // BASIC PRIMITIVE
  161. //
  162. void
  163. R_MapPlane
  164. ( int        y,
  165.   int        x1,
  166.   int        x2 )
  167. {
  168.     angle_t    angle;
  169.     fixed_t    distance;
  170.     fixed_t    length;
  171.     unsigned    index;
  172.     
  173. #ifdef RANGECHECK
  174.     if (x2 < x1
  175.     || x1<0
  176.     || x2>=viewwidth
  177.     || (unsigned)y>viewheight)
  178.     {
  179.     I_Error ("R_MapPlane: %i, %i at %i",x1,x2,y);
  180.     }
  181. #endif
  182.  
  183.     if (planeheight != cachedheight[y])
  184.     {
  185.     cachedheight[y] = planeheight;
  186.     distance = cacheddistance[y] = FixedMul (planeheight, yslope[y]);
  187.     ds_xstep = cachedxstep[y] = FixedMul (distance,basexscale);
  188.     ds_ystep = cachedystep[y] = FixedMul (distance,baseyscale);
  189.     }
  190.     else
  191.     {
  192.     distance = cacheddistance[y];
  193.     ds_xstep = cachedxstep[y];
  194.     ds_ystep = cachedystep[y];
  195.     }
  196.     
  197.     length = FixedMul (distance,distscale[x1]);
  198.     angle = (viewangle + xtoviewangle[x1])>>ANGLETOFINESHIFT;
  199.     ds_xfrac = viewx + FixedMul(finecosine[angle], length);
  200.     ds_yfrac = -viewy - FixedMul(finesine[angle], length);
  201.  
  202.     if (fixedcolormap)
  203.     ds_colormap = fixedcolormap;
  204.     else
  205.     {
  206.     index = distance >> LIGHTZSHIFT;
  207.     
  208.     if (index >= MAXLIGHTZ )
  209.         index = MAXLIGHTZ-1;
  210.  
  211.     ds_colormap = planezlight[index];
  212.     }
  213.     
  214.     ds_y = y;
  215.     ds_x1 = x1;
  216.     ds_x2 = x2;
  217.  
  218.     // high or low detail
  219.     spanfunc ();    
  220. }
  221. #endif
  222.  
  223.  
  224. //
  225. // R_ClearPlanes
  226. // At begining of frame.
  227. //
  228. void R_ClearPlanes (void)
  229. {
  230.     int        i;
  231.     angle_t    angle;
  232.     
  233.     // opening / clipping determination
  234.     for (i=0 ; i<viewwidth ; i++)
  235.     {
  236.     floorclip[i] = viewheight;
  237.     ceilingclip[i] = -1;
  238.     }
  239.  
  240.     lastvisplane = visplanes;
  241.     lastopening = openings;
  242.     
  243.     // texture calculation
  244.     // memset (cachedheight, 0, sizeof(cachedheight));
  245.     memset (cachedheight, 0, SCREENHEIGHT * sizeof(fixed_t));
  246.  
  247.     // left to right mapping
  248.     angle = (viewangle-ANG90)>>ANGLETOFINESHIFT;
  249.     
  250.     // scale will be unit scale at SCREENWIDTH/2 distance
  251.     basexscale = FixedDiv (finecosine[angle],centerxfrac);
  252.     baseyscale = -FixedDiv (finesine[angle],centerxfrac);
  253. }
  254.  
  255.  
  256.  
  257.  
  258. //
  259. // R_FindPlane
  260. //
  261. visplane_t*
  262. R_FindPlane
  263. ( fixed_t    height,
  264.   int        picnum,
  265.   int        lightlevel )
  266. {
  267.     visplane_t*    check;
  268.     
  269.     if (picnum == skyflatnum)
  270.     {
  271.     height = 0;            // all skys map together
  272.     lightlevel = 0;
  273.     }
  274.     
  275.     for (check=visplanes; check<lastvisplane; check++)
  276.     {
  277.     if (height == check->height
  278.         && picnum == check->picnum
  279.         && lightlevel == check->lightlevel)
  280.     {
  281.         break;
  282.     }
  283.     }
  284.     
  285.             
  286.     if (check < lastvisplane)
  287.     return check;
  288.         
  289.     if (lastvisplane - visplanes == MAXVISPLANES)
  290.     I_Error ("R_FindPlane: no more visplanes");
  291.         
  292.     lastvisplane++;
  293.  
  294.     check->height = height;
  295.     check->picnum = picnum;
  296.     check->lightlevel = lightlevel;
  297.     check->minx = SCREENWIDTH;
  298.     check->maxx = -1;
  299.     
  300.     //memset (check->top,0xff,sizeof(check->top));
  301.     memset (check->top,0xff,SCREENWIDTH * sizeof(unsigned short));
  302.         
  303.     return check;
  304. }
  305.  
  306.  
  307. //
  308. // R_CheckPlane
  309. //
  310. visplane_t*
  311. R_CheckPlane
  312. ( visplane_t*    pl,
  313.   int        start,
  314.   int        stop )
  315. {
  316.     int        intrl;
  317.     int        intrh;
  318.     int        unionl;
  319.     int        unionh;
  320.     int        x;
  321.     
  322.     if (start < pl->minx)
  323.     {
  324.     intrl = pl->minx;
  325.     unionl = start;
  326.     }
  327.     else
  328.     {
  329.     unionl = pl->minx;
  330.     intrl = start;
  331.     }
  332.     
  333.     if (stop > pl->maxx)
  334.     {
  335.     intrh = pl->maxx;
  336.     unionh = stop;
  337.     }
  338.     else
  339.     {
  340.     unionh = pl->maxx;
  341.     intrh = stop;
  342.     }
  343.  
  344.     for (x=intrl ; x<= intrh ; x++)
  345.     //if (pl->top[x] != 0xff)
  346.     if (pl->top[x] != 0xffff)
  347.         break;
  348.  
  349.     if (x > intrh)
  350.     {
  351.     pl->minx = unionl;
  352.     pl->maxx = unionh;
  353.  
  354.     // use the same one
  355.     return pl;        
  356.     }
  357.     
  358.     // make a new visplane
  359.     lastvisplane->height = pl->height;
  360.     lastvisplane->picnum = pl->picnum;
  361.     lastvisplane->lightlevel = pl->lightlevel;
  362.     
  363.     pl = lastvisplane++;
  364.     pl->minx = start;
  365.     pl->maxx = stop;
  366.  
  367.     //memset (pl->top,0xff,sizeof(pl->top));
  368.     memset (pl->top,0xff,SCREENWIDTH * sizeof(unsigned short));
  369.  
  370.     return pl;
  371. }
  372.  
  373.  
  374. #ifndef AMIGA
  375. #ifdef AMIGA
  376. void
  377. __asm R_MakeSpans
  378. ( register __d2 int x,
  379.   register __d3 int t1,
  380.   register __d4 int b1,
  381.   register __d5 int t2,
  382.   register __d6 int b2 )
  383. #else
  384. //
  385. // R_MakeSpans
  386. //
  387. void
  388. R_MakeSpans
  389. ( int        x,
  390.   int        t1,
  391.   int        b1,
  392.   int        t2,
  393.   int        b2 )
  394. #endif
  395. {
  396.     while (t1 < t2 && t1<=b1)
  397.     {
  398.     R_MapPlane (t1,spanstart[t1],x-1);
  399.     t1++;
  400.     }
  401.     while (b1 > b2 && b1>=t1)
  402.     {
  403.     R_MapPlane (b1,spanstart[b1],x-1);
  404.     b1--;
  405.     }
  406.     
  407.     while (t2 < t1 && t2<=b2)
  408.     {
  409.     spanstart[t2] = x;
  410.     t2++;
  411.     }
  412.     while (b2 > b1 && b2>=t2)
  413.     {
  414.     spanstart[b2] = x;
  415.     b2--;
  416.     }
  417. }
  418. #endif
  419.  
  420.  
  421.  
  422. #ifndef AMIGA
  423. //
  424. // R_DrawPlanes
  425. // At the end of each frame.
  426. //
  427. void R_DrawPlanes (void)
  428. {
  429.     visplane_t*        pl;
  430.     int            light;
  431.     int            x;
  432.     int            stop;
  433.     int            angle;
  434.                 
  435. #ifdef RANGECHECK
  436.     if (ds_p - drawsegs > MAXDRAWSEGS)
  437.     I_Error ("R_DrawPlanes: drawsegs overflow (%i)",
  438.          ds_p - drawsegs);
  439.     
  440.     if (lastvisplane - visplanes > MAXVISPLANES)
  441.     I_Error ("R_DrawPlanes: visplane overflow (%i)",
  442.          lastvisplane - visplanes);
  443.     
  444.     if (lastopening - openings > MAXOPENINGS)
  445.     I_Error ("R_DrawPlanes: opening overflow (%i)",
  446.          lastopening - openings);
  447. #endif
  448.  
  449.     for (pl = visplanes ; pl < lastvisplane ; pl++)
  450.     {
  451.     if (pl->minx > pl->maxx)
  452.         continue;
  453.  
  454.     
  455.     // sky flat
  456.     if (pl->picnum == skyflatnum)
  457.     {
  458.         dc_iscale = pspriteiscale2>>detailshift;
  459.         
  460.         // Sky is allways drawn full bright,
  461.         //  i.e. colormaps[0] is used.
  462.         // Because of this hack, sky is not affected
  463.         //  by INVUL inverse mapping.
  464.         dc_colormap = colormaps;
  465.         dc_texturemid = skytexturemid;
  466.         for (x=pl->minx ; x <= pl->maxx ; x++)
  467.         {
  468.         dc_yl = pl->top[x];
  469.         dc_yh = pl->bottom[x];
  470.  
  471.         if (dc_yl <= dc_yh)
  472.         {
  473.             angle = (viewangle + xtoviewangle[x])>>ANGLETOSKYSHIFT;
  474.             dc_x = x;
  475.             dc_source = R_GetColumn(skytexture, angle);
  476.             colfunc ();
  477.         }
  478.         }
  479.         continue;
  480.     }
  481.     
  482.     // regular flat
  483.     ds_source = W_CacheLumpNum(firstflat +
  484.                    flattranslation[pl->picnum],
  485.                    PU_STATIC);
  486.     
  487.     planeheight = iabs(pl->height-viewz);
  488.     light = (pl->lightlevel >> LIGHTSEGSHIFT)+extralight;
  489.  
  490.     if (light >= LIGHTLEVELS)
  491.         light = LIGHTLEVELS-1;
  492.  
  493.     if (light < 0)
  494.         light = 0;
  495.  
  496.     planezlight = zlight[light];
  497.  
  498.     //pl->top[pl->maxx+1] = 0xff;
  499.     //pl->top[pl->minx-1] = 0xff;
  500.     pl->top[pl->maxx+1] = 0xffff;
  501.     pl->top[pl->minx-1] = 0xffff;
  502.         
  503.     stop = pl->maxx + 1;
  504.  
  505.     for (x=pl->minx ; x<= stop ; x++)
  506.     {
  507.         R_MakeSpans(x,pl->top[x-1],
  508.             pl->bottom[x-1],
  509.             pl->top[x],
  510.             pl->bottom[x]);
  511.     }
  512.     
  513.     Z_ChangeTag (ds_source, PU_CACHE);
  514.     }
  515. }
  516. #endif
  517.